using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NAudio.Midi;
using System.IO;

namespace MKDS_Course_Editor.GCN.Sound
{
    public partial class BMS : Form
    {
        string file;
        MidiEventCollection ef = new MidiEventCollection(1, 48);
        public BMS(string file)
        {
            InitializeComponent();
            this.file = file;
        }

        private void BMS_Load(object sender, EventArgs e)
        {
            EndianBinaryReader er = new EndianBinaryReader(File.OpenRead(file), Endianness.BigEndian);
            List<int> trackoffsets = new List<int>();
            while (er.BaseStream.Position != er.BaseStream.Length)
            {
                switch (er.ReadByte())
                {
                    case 0xb8://global speakers
                        {
                            er.ReadBytes(3);
                            break;
                        }
                    case 0xc1://Trackoffset
                        {
                            int offset = er.ReadInt32();
                            ef.AddTrack();
                            trackoffsets.Add(offset);
                            break;
                        }
                    case 0xc7://loop to offset
                        {
                            byte[] b2 = er.ReadBytes(3);
                            int off = int.Parse(BitConverter.ToString(b2).Replace("-", ""), System.Globalization.NumberStyles.HexNumber);
                            break;
                        }
                    case 0xd8://unknown
                        {
                            er.ReadBytes(3);
                            break;
                        }
                    case 0xe0://tempo
                        {
                            int tempo = 60 / er.ReadInt16();
                            foreach (IList<MidiEvent> d in ef)
                            {
                                d.Add(new TempoEvent(tempo, 0));
                            }
                            break;
                        }
                    case 0xf0://length
                        {
                            int l = sseq.DecodeInt32(er);
                            break;
                        }
                    case 0xff://end
                        goto track;
                }
            }
            track:
            for(int i = 0; i < ef.Tracks; i++)
            {
                er.BaseStream.Position = trackoffsets[i];
                while (er.BaseStream.Position != er.BaseStream.Length)
                {
                    switch (er.ReadByte())
                    {
                        case 0xb8://global speakers
                            {
                                er.ReadBytes(3);
                                break;
                            }
                        case 0xc1://Tracknumber
                            {
                                int nr = er.ReadByte();
                                break;
                            }
                        case 0xc7://loop to offset
                            {
                                byte[] b2 = er.ReadBytes(3);
                                int off = int.Parse(BitConverter.ToString(b2).Replace("-", ""), System.Globalization.NumberStyles.HexNumber);
                                break;
                            }
                        case 0xd8://unknown
                            {
                                er.ReadBytes(3);
                                break;
                            }
                        case 0xe0://tempo
                            {
                                int tempo = 60 / er.ReadInt16();
                                foreach (IList<MidiEvent> d in ef)
                                {
                                    d.Add(new TempoEvent(tempo, 0));
                                }
                                break;
                            }
                        case 0xf0://length
                            {
                                int l = sseq.DecodeInt32(er);
                                break;
                            }
                        case 0xff://end
                            break;
                    }
                }
            }
            er.Close();
            ef.PrepareForExport();
            MidiFile.Export(@"C:\test.mid", ef);
        }
    }
}
